// 存储配置类型
export type StorageType = 'indexedDB' | 'supabase';

// 存储配置接口
export interface StorageConfig {
  type: StorageType;
  supabaseUrl?: string;
  supabaseKey?: string;
}

// 通用存储适配器接口
export interface StorageAdapter<T = any> {
  save(storeName: string, data: T[]): Promise<void>;
  load(storeName: string): Promise<T[]>;
  findById(storeName: string, id: string): Promise<T | null>;
  delete(storeName: string, id: string): Promise<void>;
  deleteMany(storeName: string, ids: string[]): Promise<void>;
  clear(storeName: string): Promise<void>;
}

// 项目统一配置
export const PROJECT_CONFIG = {
  // 统一的数据库名称
  DB_NAME: 'InvestToolsDB',
  DB_VERSION: 2, // 增加版本号以触发数据库升级
  // 业务存储名称定义 - 映射到Supabase表名
  STORE_NAMES: {
    FUND_PLANS: 'fund_investment_plans',          // 公募基金投资计划
    STOCK_PLANS: 'stock_investment_plans',        //证券投资计划
    PROFIT_CALCULATIONS: 'profit_calculations',    // 收益计算
    USER_SETTINGS: 'user_settings',               // 用户设置
    // 后续可以继续添加新的业务存储
  }
} as const;

// IndexedDB 适配器
export class IndexedDBAdapter<T extends { id: string }> implements StorageAdapter<T> {
  private dbName: string;
  private version: number;

  constructor(dbName: string = PROJECT_CONFIG.DB_NAME, version: number = PROJECT_CONFIG.DB_VERSION) {
    this.dbName = dbName;
    this.version = version;
  }

  private async openDB(): Promise<IDBDatabase> {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open(this.dbName, this.version);
      
      request.onerror = () => {
        console.error('IndexedDB 打开失败:', request.error);
        reject(request.error);
      };
      
      request.onsuccess = () => {
        const db = request.result;
        console.log('IndexedDB 打开成功, 现有 stores:', Array.from(db.objectStoreNames));
        resolve(db);
      };
      
      request.onupgradeneeded = (event) => {
        const db = (event.target as IDBOpenDBRequest).result;
        console.log('IndexedDB 升级中, 当前版本:', event.oldVersion, '目标版本:', event.newVersion);
        
        // 创建所有预定义的存储对象
        Object.values(PROJECT_CONFIG.STORE_NAMES).forEach(storeName => {
          if (!db.objectStoreNames.contains(storeName)) {
            console.log('创建 object store:', storeName);
            const store = db.createObjectStore(storeName, { keyPath: 'id' });
            store.createIndex('createdAt', 'createdAt', { unique: false });
            store.createIndex('updatedAt', 'updatedAt', { unique: false });
          } else {
            console.log('Object store 已存在:', storeName);
          }
        });
        
        console.log('IndexedDB 升级完成, 所有 stores:', Array.from(db.objectStoreNames));
      };
    });
  }

  async save(storeName: string, data: T[]): Promise<void> {
    try {
      const db = await this.openDB();
      
      // 检查 object store 是否存在
      if (!db.objectStoreNames.contains(storeName)) {
        console.error(`Object store '${storeName}' 不存在，无法保存数据`);
        db.close();
        throw new Error(`Object store '${storeName}' 不存在`);
      }
      
      const transaction = db.transaction([storeName], 'readwrite');
      const store = transaction.objectStore(storeName);
      
      // 清空现有数据
      await new Promise<void>((resolve, reject) => {
        const clearRequest = store.clear();
        clearRequest.onsuccess = () => resolve();
        clearRequest.onerror = () => reject(clearRequest.error);
      });
      
      // 保存新数据
      for (const item of data) {
        await new Promise<void>((resolve, reject) => {
          const addRequest = store.add(item);
          addRequest.onsuccess = () => resolve();
          addRequest.onerror = () => reject(addRequest.error);
        });
      }
      
      db.close();
    } catch (error) {
      throw new Error(`IndexedDB 保存失败 [${storeName}]: ${error}`);
    }
  }

  async load(storeName: string): Promise<T[]> {
    try {
      const db = await this.openDB();
      
      // 检查 object store 是否存在
      if (!db.objectStoreNames.contains(storeName)) {
        console.warn(`Object store '${storeName}' 不存在，返回空数组`);
        db.close();
        return [];
      }
      
      const transaction = db.transaction([storeName], 'readonly');
      const store = transaction.objectStore(storeName);
      
      const data = await new Promise<T[]>((resolve, reject) => {
        const request = store.getAll();
        request.onsuccess = () => resolve(request.result);
        request.onerror = () => reject(request.error);
      });
      
      db.close();
      return data.sort((a: any, b: any) => {
        const aTime = new Date(a.createdAt || a.updatedAt || 0).getTime();
        const bTime = new Date(b.createdAt || b.updatedAt || 0).getTime();
        return bTime - aTime;
      });
    } catch (error) {
      console.error(`IndexedDB 读取失败 [${storeName}]:`, error);
      return [];
    }
  }

  async findById(storeName: string, id: string): Promise<T | null> {
    try {
      const db = await this.openDB();
      
      // 检查 object store 是否存在
      if (!db.objectStoreNames.contains(storeName)) {
        console.warn(`Object store '${storeName}' 不存在，返回 null`);
        db.close();
        return null;
      }
      
      const transaction = db.transaction([storeName], 'readonly');
      const store = transaction.objectStore(storeName);
      
      const data = await new Promise<T | undefined>((resolve, reject) => {
        const request = store.get(id);
        request.onsuccess = () => resolve(request.result);
        request.onerror = () => reject(request.error);
      });
      
      db.close();
      return data || null;
    } catch (error) {
      console.error(`IndexedDB 查询失败 [${storeName}]:`, error);
      return null;
    }
  }

  async delete(storeName: string, id: string): Promise<void> {
    try {
      const db = await this.openDB();
      const transaction = db.transaction([storeName], 'readwrite');
      const store = transaction.objectStore(storeName);
      
      await new Promise<void>((resolve, reject) => {
        const deleteRequest = store.delete(id);
        deleteRequest.onsuccess = () => resolve();
        deleteRequest.onerror = () => reject(deleteRequest.error);
      });
      
      db.close();
    } catch (error) {
      throw new Error(`IndexedDB 删除失败 [${storeName}]: ${error}`);
    }
  }

  async deleteMany(storeName: string, ids: string[]): Promise<void> {
    try {
      const db = await this.openDB();
      const transaction = db.transaction([storeName], 'readwrite');
      const store = transaction.objectStore(storeName);
      
      for (const id of ids) {
        await new Promise<void>((resolve, reject) => {
          const deleteRequest = store.delete(id);
          deleteRequest.onsuccess = () => resolve();
          deleteRequest.onerror = () => reject(deleteRequest.error);
        });
      }
      
      db.close();
    } catch (error) {
      throw new Error(`IndexedDB 批量删除失败 [${storeName}]: ${error}`);
    }
  }

  async clear(storeName: string): Promise<void> {
    try {
      const db = await this.openDB();
      const transaction = db.transaction([storeName], 'readwrite');
      const store = transaction.objectStore(storeName);
      
      await new Promise<void>((resolve, reject) => {
        const clearRequest = store.clear();
        clearRequest.onsuccess = () => resolve();
        clearRequest.onerror = () => reject(clearRequest.error);
      });
      
      db.close();
    } catch (error) {
      throw new Error(`IndexedDB 清空失败 [${storeName}]: ${error}`);
    }
  }
}

// Supabase 适配器
export class SupabaseAdapter<T extends { id: string }> implements StorageAdapter<T> {
  private supabase: any;
  private fieldTransformer?: any;

  constructor(url: string, key: string, fieldTransformer?: any) {
    this.fieldTransformer = fieldTransformer;
    // 动态导入 Supabase 客户端
    import('../../config/supabase').then(({ supabase }) => {
      this.supabase = supabase;
    });
  }

  private async getSupabaseClient() {
    if (!this.supabase) {
      const { supabase } = await import('../../config/supabase');
      this.supabase = supabase;
    }
    return this.supabase;
  }

  private async getCurrentUserId(): Promise<string> {
    try {
      const userStr = localStorage.getItem('user');
      if (!userStr) {
        throw new Error('用户未登录');
      }
      
      const user = JSON.parse(userStr);
      if (!user?.id) {
        throw new Error('用户未登录');
      }
      
      return user.id;
    } catch (error) {
      throw new Error('用户未登录');
    }
  }

  async save(storeName: string, data: T[]): Promise<void> {
    try {
      const supabase = await this.getSupabaseClient();
      const userId = await this.getCurrentUserId();
      
      // 为每个数据项添加用户ID和时间戳
      const dataWithUserId = data.map(item => {
        const now = new Date().toISOString();
        return {
          ...item,
          user_id: userId,
          updated_at: now,
          // 如果没有created_at，则添加
          ...((item as any).created_at ? {} : { created_at: now })
        };
      });

      // 转换字段名为数据库格式
      const transformedData = this.fieldTransformer 
        ? this.fieldTransformer.toBDBatch(dataWithUserId)
        : dataWithUserId;

      // 使用 upsert 操作，如果存在则更新，不存在则插入
      const { error } = await supabase
        .from(storeName)
        .upsert(transformedData, { onConflict: 'id' });

      if (error) {
        throw new Error(`Supabase 保存失败: ${error.message}`);
      }
    } catch (error) {
      throw new Error(`Supabase 保存失败 [${storeName}]: ${error}`);
    }
  }

  async load(storeName: string): Promise<T[]> {
    try {
      const supabase = await this.getSupabaseClient();
      const userId = await this.getCurrentUserId();
      
      const { data, error } = await supabase
        .from(storeName)
        .select('*')
        .eq('user_id', userId)
        .order('created_at', { ascending: false });

      if (error) {
        throw new Error(`Supabase 读取失败: ${error.message}`);
      }

      // 转换字段名为前端格式
      const transformedData = this.fieldTransformer 
        ? this.fieldTransformer.fromDBBatch(data || [])
        : data || [];

      return transformedData;
    } catch (error) {
      console.error(`Supabase 读取失败 [${storeName}]:`, error);
      return [];
    }
  }

  async findById(storeName: string, id: string): Promise<T | null> {
    try {
      const supabase = await this.getSupabaseClient();
      const userId = await this.getCurrentUserId();
      
      const { data, error } = await supabase
        .from(storeName)
        .select('*')
        .eq('id', id)
        .eq('user_id', userId)
        .single();

      if (error) {
        if (error.code === 'PGRST116') {
          // 没有找到记录
          return null;
        }
        throw new Error(`Supabase 查询失败: ${error.message}`);
      }

      // 转换字段名为前端格式
      const transformedData = this.fieldTransformer 
        ? this.fieldTransformer.fromDB(data)
        : data;

      return transformedData;
    } catch (error) {
      console.error(`Supabase 查询失败 [${storeName}]:`, error);
      return null;
    }
  }

  async delete(storeName: string, id: string): Promise<void> {
    try {
      const supabase = await this.getSupabaseClient();
      const userId = await this.getCurrentUserId();
      
      const { error } = await supabase
        .from(storeName)
        .delete()
        .eq('id', id)
        .eq('user_id', userId);

      if (error) {
        throw new Error(`Supabase 删除失败: ${error.message}`);
      }
    } catch (error) {
      throw new Error(`Supabase 删除失败 [${storeName}]: ${error}`);
    }
  }

  async deleteMany(storeName: string, ids: string[]): Promise<void> {
    try {
      const supabase = await this.getSupabaseClient();
      const userId = await this.getCurrentUserId();
      
      const { error } = await supabase
        .from(storeName)
        .delete()
        .in('id', ids)
        .eq('user_id', userId);

      if (error) {
        throw new Error(`Supabase 批量删除失败: ${error.message}`);
      }
    } catch (error) {
      throw new Error(`Supabase 批量删除失败 [${storeName}]: ${error}`);
    }
  }

  async clear(storeName: string): Promise<void> {
    try {
      const supabase = await this.getSupabaseClient();
      const userId = await this.getCurrentUserId();
      
      const { error } = await supabase
        .from(storeName)
        .delete()
        .eq('user_id', userId);

      if (error) {
        throw new Error(`Supabase 清空失败: ${error.message}`);
      }
    } catch (error) {
      throw new Error(`Supabase 清空失败 [${storeName}]: ${error}`);
    }
  }
}

// 基础存储服务类
export abstract class BaseStorageService<T extends { id: string }> {
  protected adapter: StorageAdapter<T>;
  protected storeName: string;
  protected config: StorageConfig;
  protected fieldTransformer?: any;

  constructor(storeName: string, config: StorageConfig = { type: 'indexedDB' }, fieldTransformer?: any) {
    this.storeName = storeName;
    this.config = config;
    this.fieldTransformer = fieldTransformer;
    this.adapter = this.createAdapter(config);
  }

  private createAdapter(config: StorageConfig): StorageAdapter<T> {
    switch (config.type) {
      case 'indexedDB':
        return new IndexedDBAdapter<T>();
      case 'supabase':
        if (!config.supabaseUrl || !config.supabaseKey) {
          throw new Error('Supabase 配置缺少 URL 或 Key');
        }
        // 传递字段转换器给 SupabaseAdapter
        return new SupabaseAdapter<T>(config.supabaseUrl, config.supabaseKey, (this as any).fieldTransformer);
      default:
        throw new Error(`不支持的存储类型: ${config.type}`);
    }
  }

  // 切换存储方案
  async switchStorage(newConfig: StorageConfig): Promise<void> {
    try {
      // 先备份当前数据
      const currentData = await this.getAll();
      
      // 切换适配器
      this.config = newConfig;
      this.adapter = this.createAdapter(newConfig);
      
      // 迁移数据到新存储
      if (currentData.length > 0) {
        await this.adapter.save(this.storeName, currentData);
      }
    } catch (error) {
      throw new Error(`存储方案切换失败 [${this.storeName}]: ${error}`);
    }
  }

  // 基础 CRUD 操作
  async save(item: T): Promise<void> {
    try {
      // 对于Supabase适配器，直接保存单个项目
      if (this.config.type === 'supabase') {
        const now = new Date().toISOString();
        const existingItem = await this.getById(item.id);
        
        const itemWithTimestamp = {
          ...item,
          // updated_at: now,
          // 如果是新项目，添加创建时间
          ...(!existingItem && { created_at: now })
        } as T;
        
        await this.adapter.save(this.storeName, [itemWithTimestamp]);
      } else {
        // IndexedDB的原有逻辑
        const existingData = await this.getAll();
        const existingIndex = existingData.findIndex(d => d.id === item.id);
        
        let updatedData: T[];
        if (existingIndex >= 0) {
          // 更新现有数据
          updatedData = [...existingData];
          updatedData[existingIndex] = { ...item, updatedAt: new Date().toISOString() } as T;
        } else {
          // 新增数据
          updatedData = [...existingData, { ...item, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() } as T];
        }
        
        await this.adapter.save(this.storeName, updatedData);
      }
    } catch (error) {
      throw new Error(`保存数据失败 [${this.storeName}]: ${error}`);
    }
  }

  async getAll(): Promise<T[]> {
    try {
      return await this.adapter.load(this.storeName);
    } catch (error) {
      console.error(`获取数据失败 [${this.storeName}]:`, error);
      return [];
    }
  }

  async getById(id: string): Promise<T | null> {
    try {
      return await this.adapter.findById(this.storeName, id);
    } catch (error) {
      console.error(`获取数据失败 [${this.storeName}]:`, error);
      return null;
    }
  }

  async delete(id: string): Promise<void> {
    try {
      await this.adapter.delete(this.storeName, id);
    } catch (error) {
      throw new Error(`删除数据失败 [${this.storeName}]: ${error}`);
    }
  }

  async deleteMany(ids: string[]): Promise<void> {
    try {
      await this.adapter.deleteMany(this.storeName, ids);
    } catch (error) {
      throw new Error(`批量删除数据失败 [${this.storeName}]: ${error}`);
    }
  }

  async clear(): Promise<void> {
    try {
      await this.adapter.clear(this.storeName);
    } catch (error) {
      throw new Error(`清空数据失败 [${this.storeName}]: ${error}`);
    }
  }

  // 导出导入功能
  async exportAll(): Promise<string> {
    try {
      const data = await this.getAll();
      return JSON.stringify(data, null, 2);
    } catch (error) {
      throw new Error(`导出数据失败 [${this.storeName}]: ${error}`);
    }
  }

  async import(jsonData: string): Promise<void> {
    try {
      const data: T[] = JSON.parse(jsonData);
      
      // 验证数据格式
      if (!Array.isArray(data)) {
        throw new Error('导入数据格式错误：应为数组格式');
      }
      
      // 验证每个数据项的必要字段
      for (const item of data) {
        if (!item.id) {
          throw new Error('导入数据格式错误：缺少 id 字段');
        }
      }
      
      await this.adapter.save(this.storeName, data);
    } catch (error) {
      throw new Error(`导入数据失败 [${this.storeName}]: ${error}`);
    }
  }

  // 获取当前存储配置
  getStorageConfig(): StorageConfig {
    return { ...this.config };
  }

  // 获取存储名称
  getStoreName(): string {
    return this.storeName;
  }
}